﻿using HuChaHuRen.HeNan.Common;
using HuChaHuRen.HeNan.Models;
using HuChaHuRen.HeNan.XiangCheng.Common;
using HuChaHuRen.HeNan.XiangCheng.Models.Messages;
using HuChaHuRen.HeNan.XiangCheng.Models.Others;
using HuChaHuRen.HeNan.XiangCheng.Upload;
using LazyCache;
using Newtonsoft.Json;
using PACS.Client.Model;
using Quartz;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HuChaHuRen.HeNan.Upload
{
    public class ReportFileUploadJob : IJob
    {
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger("PACSUploadJob");
        private BaseConfig baseCfg = ConfigHelp.GetBaseConfig();
        IAppCache _appCache = null;

        public void Execute(IJobExecutionContext context)
        {
            PublishStatus("运行中...");
            Publish("进入 [ReportFileUploadJob] 方法.");
            object appCache = context.JobDetail.JobDataMap.Get("AppCache");
            if (appCache != null)
            {
                _appCache = (IAppCache)appCache;
            }

            var dbContext = DataProvider.GetNewConn();
            if (dbContext == null)
            {
                PublishError("数据库连接失败,请检查连接字符串.");
                return;
            }
            else
            {
                dbContext.Ado.CommandTimeOut = 5000;
            }
            int searchRange = baseCfg.UploadRecordDateRange;
            if (searchRange <= 0)
            {
                searchRange = 3;
            }

            DateTime searchStartTime = DateTime.Now.AddDays(-searchRange);

            List<OrgConfig> orgList = baseCfg.OrgConfigs;
            if (orgList == null || orgList.Count == 0)
            {
                PublishError($"未配置机构信息,任务终止.");
                PublishStatus("就绪");
                return;
            }

            List<string> orgIds = orgList.Select(it => it.OrgID).ToList();
            List<OrganizationInfo> orgRecordList = null;
            bool hasOrgRecord = _appCache.TryGetValue<List<OrganizationInfo>>(CommonValue.OrgListKey, out orgRecordList);

            if (!hasOrgRecord)
            {
                try
                {
                    orgRecordList = dbContext.Queryable<OrganizationInfo>()
                           .In(it => it.Id, orgIds)
                           .ToList();
                    if (orgRecordList != null && orgRecordList.Any())
                    {
                        _appCache.Add(CommonValue.OrgListKey, orgRecordList, DateTimeOffset.Now.AddDays(1));
                    }
                    else
                    {
                        string err = $"OrgConfigs 没有任何机构配置,报告上传终止。";
                        logger.Error(err);
                        return;
                    }

                }
                catch (Exception ex)
                {
                    PublishError($"查询'OrganizationInfo'失败,请检查数据库连接.\n{ex.Message}");
                    PublishError($"{nameof(PACSUploadJob)}Job已终止");
                    PublishStatus("就绪");
                    return;
                }
            }

            List<HCHR_UploadRecord> repUploadList = new List<HCHR_UploadRecord>();
            try
            {
                //查询已经上传登记记录和报告记录的Study记录
                repUploadList = dbContext.Queryable<Study, HCHR_UploadRecord, HCHR_ReportFileUploadRecord>((stu, repUploadRec, fileUploadRec) => new object[] {
                    JoinType.Left,stu.Id == repUploadRec.ID,
                    JoinType.Left,stu.Id == fileUploadRec.StudyID })
                    .Where((stu, repUploadRec, fileUploadRec) => stu.CreateTime > searchStartTime)
                    .Where((stu, repUploadRec, fileUploadRec) => (repUploadRec.StudyUploadSucceed == true && repUploadRec.ReportUploadSucceed == false && repUploadRec.ErrorMessage == null))
                    .Where((stu, repUploadRec, fileUploadRec) => SqlFunc.IsNullOrEmpty(fileUploadRec.ID) || fileUploadRec.UploadSucceed == false)
                    .Select((stu, repUploadRec, fileUploadRec) => repUploadRec)
                    .ToList();

            }
            catch (Exception ex)
            {
                PublishError($"{nameof(PACSUploadJob)}查询检查异常:\n{ex.Message}");
                PublishStatus("就绪");
                return;
            }

            if (repUploadList != null && repUploadList.Any())
            {
                Publish($"查询到 {repUploadList.Count} 条需要上传的报告记录.");
                var stuIdList = repUploadList.Select(it => it.StudyID).ToList();
                var patQuery = dbContext.Queryable<Patient, Study>((pat, stu) => new object[]
                    { 
                        JoinType.Left, pat.Id == stu.PatientID
                    })
                    .In((pat, stu) => stu.Id, stuIdList)
                    .Select((pat, stu) => new { PID = pat.Id, SID = stu.Id, OrgId = pat.OrgID })
                    .ToList();



                foreach (var record in repUploadList)
                {
                    var matchInfo = patQuery.FirstOrDefault(it => it.SID == record.StudyID);
                    string hospCode = orgList.FirstOrDefault(it => it.OrgID == matchInfo.OrgId).HospitalCode;
                    if (!string.IsNullOrEmpty(hospCode))
                    {
                        FinalFileRequest request = new FinalFileRequest();
                        request.providerID = baseCfg.PlatformConfig.ProviderID;
                        string timesmp = DateTime.Now.ToString("yyyyMMddHHmmss");
                        request.timestamp = timesmp;
                        request.providerKey = Hash.CalculateMD5($"{baseCfg.PlatformConfig.Password}{timesmp}");
                        request.hospitalCode = hospCode;
                        request.studyPk = record.StudyPK;
                        Dictionary<string, string> headers = new Dictionary<string, string>
                        {
                            { "ProviderID", request.providerID },
                            { "ProviderKey", request.providerKey },
                            { "Timestamp", request.timestamp },
                            { "HospitalCode", request.hospitalCode },
                            { "StudyPk", request.studyPk }
                        };
                        string fileName = $"{hospCode}_{record.StudyID}.pdf";
                        var repFile = dbContext.Queryable<ReportFile>()
                            .Where(it => it.StudyID == record.StudyID)
                            .First();

                        string resp = string.Empty;
                        try
                        {
                            string repFileUploadUrl = baseCfg.PlatformConfig.Host + baseCfg.PlatformConfig.ReportFileUploadUrl;
                            resp = HttpOp.PostMultipartFormData(repFileUploadUrl,
                                                headers,
                                                null,
                                                fileName,
                                                repFile.ReportPDF);
                        }
                        catch (Exception ex)
                        {
                            string err = $"上传pdf发生异常:\n{ex.Message}";
                            logger.Error(err);
                        }

                        if (!string.IsNullOrEmpty(resp))
                        {
                            try
                            {
                                Response respEntity = JsonConvert.DeserializeObject<Response>(resp);
                            }
                            catch (Exception ex)
                            {
                                string err = $"解析上传响应失败:\n{ex.Message}";
                                logger.Error(err);
                            }
                        }
                        else
                        {
                            string err = $"上传pdf返回结果为空,StudyID: {record.StudyID}.";
                            logger.Error(err);
                        }
                    }
                    else
                    {
                        string err = $"当前机构({matchInfo.OrgId})没有配置HospitalCode，跳过上传";
                        logger.Error(err);
                        continue;
                    }
                }
            }
            else
            {
                Publish("没有需要上传的报告记录.");
            }
        }

        private void Publish(string msg)
        {
            logger.Info(msg);
            MessageHub.DefaultMessageHub.SendMessage<string>(msg);
        }

        private void PublishError(string msg)
        {
            logger.Error(msg);
            MessageHub.DefaultMessageHub.SendMessage<string>(msg);
        }

        private void PublishStatus(string status)
        {
            MessageHub.DefaultMessageHub.SendMessage<JobActivityMessage>(new JobActivityMessage
            {
                JobType = 3,
                Status = status
            });
        }
    }
}
